package com.yxhl.zoume.core.expresscar.fragment;

import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.yxhl.protobuf.BizOrder;
import com.yxhl.protobuf.BizOrderResponse;
import com.yxhl.protobuf.OrderBizType;
import com.yxhl.zoume.R;
import com.yxhl.zoume.common.ui.activity.base.BaseActivityWithToolBar;
import com.yxhl.zoume.core.expresscar.activity.ExpressCarScheduleActivity;
import com.yxhl.zoume.core.expresscar.helper.DriverPhonePopupWindow;
import com.yxhl.zoume.core.expresscar.helper.ScheduleAnimatorHelper;
import com.yxhl.zoume.core.expresscar.presenter.ExpressCarScheduleMapPresenter;
import com.yxhl.zoume.core.expresscar.view.ExpressCarScheduleMapView;
import com.yxhl.zoume.core.func.map.ui.fragment.BaseMapFragment;
import com.yxhl.zoume.core.func.pay.model.CarPaymentEntrance;
import com.yxhl.zoume.core.specialcar.model.CarPaymentInfo;
import com.yxhl.zoume.core.specialcar.model.DialTelephoneEvent;
import com.yxhl.zoume.core.specialcar.model.SpecialCarRideStatus;
import com.yxhl.zoume.di.component.car.DaggerExpressCarComponent;
import com.yxhl.zoume.di.module.ActivityModule;
import com.yxhl.zoume.domain.interactor.ZMEventSubscriber;
import com.yxhl.zoume.utils.DeviceUtils;
import com.yxhl.zoume.utils.PromptUtils;
import com.yxhl.zoume.utils.ZMDialog;
import com.yxhl.zoume.utils.permission.PermissionHelper;

import java.util.LinkedList;
import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import rx.functions.Action1;

/**
 * Author：zhongshan   
 * Date：2016/12/08 18:48      
 * Description：专车－下单
 */
public class ExpressCarScheduleMapFragment extends BaseMapFragment implements ExpressCarScheduleMapView {

    @BindView(R.id.map_include)
    public MapView mMapView;

    @BindView(R.id.frame_express_car_service_location)
    LinearLayout mLocationFrame;

    //分时租车时间里程栏
    @BindView(R.id.tv_express_car_schedule_time)
    TextView mScheduleTimeTv;
    @BindView(R.id.tv_express_car_schedule_distance)
    TextView mScheduleDistance;
    @BindView(R.id.ll_express_car_bottom_schedule_time_distance_bar)
    LinearLayout mScheduleTimeDistanceBar;

    //司机信息栏
    @BindView(R.id.iv_express_car_service_driver_info_phone)
    ImageView mDriverInfoPhoneIv;
    @BindView(R.id.tv_express_car_service_driver_info_title)
    TextView mDriverInfoNameTv;
    @BindView(R.id.tv_car_info)
    TextView mCarInfoTv;
    @BindView(R.id.tv_overall_rating)
    TextView mOverallRatingTv;
    @BindView(R.id.rl_express_car_service_driver_info_container)
    RelativeLayout mDriverInfoRl;

    //调度信息栏
    @BindView(R.id.tv_express_car_service_schedule_title)
    TextView mScheduleTitleTv;
    @BindView(R.id.iv_express_car_service_schedule_icon)
    ImageView mScheduleIconIv;
    @BindView(R.id.rl_express_car_service_schedule_hint)
    RelativeLayout mScheduleBarRl;

    @BindView(R.id.rl_express_car_service_header_container)
    RelativeLayout mHeaderContainerRl;
    @BindView(R.id.frame_fragment_express_car_schedule_root)
    FrameLayout mRootFrame;

    @Inject
    ExpressCarScheduleMapPresenter scheduleMapPresenter;
    @Inject
    ScheduleAnimatorHelper scheduleAnimatorHelper;

    /**
     * 第二次地图移动的边距
     */
    public static final int MOVE_PADDING = 20;
    private static final int SECOND_ANIMATE_MOVE_DELAY = 1000;
    private static final String ARGUMENT_KEY_EXPRESS_CAR_SCHEDULE_MAP = "argument_key_express_car_schedule_map";
    private static final float MAP_ZOOM_LEVEL = 13;

    private String mOrderId;
    private AMap aMap;
    private String mDriverMobile;
    private DriverPhonePopupWindow mPhonePopupWindow;

    /**
     * 出发点经纬度
     */
    private List<com.yxhl.protobuf.Location> mDepartLatLngList;

    /**
     * 目的地经纬度
     */
    private List<com.yxhl.protobuf.Location> mArrivalLatLngList;
    private ZMDialog paymentDialog;
    private ZMDialog timeOutDialog;
    private ZMDialog arrivalDialog;
    private ZMDialog driverCloseDialog;
    private ZMDialog invalidDataDialog;
    private boolean isPollingStop;

    public static ExpressCarScheduleMapFragment newInstance(String expressCarOrderId) {
        ExpressCarScheduleMapFragment fragment = new ExpressCarScheduleMapFragment();
        Bundle args = new Bundle();
        args.putString(ARGUMENT_KEY_EXPRESS_CAR_SCHEDULE_MAP, expressCarOrderId);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initArguments();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        aMap = mMapView.getMap();
        scheduleMapPresenter.attachView(this);
        scheduleMapPresenter.init(aMap);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mBaseStartMoveToLocation = true;
        scheduleMapPresenter.startPolling(mActivity, mOrderId);
    }

    @Override
    public void onResume() {
        super.onResume();
        scheduleMapPresenter.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        scheduleMapPresenter.onPause();
    }

    @Override
    public void onDestroyView() {
        if (mPhonePopupWindow != null)
            mPhonePopupWindow.dismiss();
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        scheduleMapPresenter.onDestroy();
        getSubscription().unsubscribe();
        if (!isPollingStop)
            scheduleMapPresenter.stopPolling(mActivity);
        super.onDestroy();
    }

    @Override
    protected void initializeInjector() {
        DaggerExpressCarComponent.builder()
                .activityModule(new ActivityModule(mActivity))
                .appComponent(getAppComponent())
                .build()
                .inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_express_car_schedule;
    }

    @Override
    protected void setupToolBar() {
        BaseActivityWithToolBar scheduleActivity = (BaseActivityWithToolBar) mActivity;
        scheduleActivity.setToolbar(getString(R.string.route_detail_no_charter),
                getString(R.string.special_car_operation_cancel_trip));
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            setupToolBar();
        }
    }

    @Override
    protected Marker getLocationMarker(AMap aMap, LatLng latLng) {
        return null;
    }

    @Override
    protected boolean setUpLocationStyle(AMap aMap) {
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_user_location));
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);
        myLocationStyle.strokeColor(Color.TRANSPARENT);
        aMap.setMyLocationStyle(myLocationStyle);
        return true;
    }

    @Override
    protected float getLocationMapZoomLevel() {
        return MAP_ZOOM_LEVEL;
    }

    @Override
    protected void secondAnimateMove() {
        final List<LatLng> latLngList = new LinkedList<>();
        if (mDepartLatLngList != null && mDepartLatLngList.size() > 0) {
            for (com.yxhl.protobuf.Location location : mDepartLatLngList) {
                String lat = location.getLat();
                String lng = location.getLng();
                double latDouble;
                double lngDouble;
                try {
                    latDouble = Double.parseDouble(lat);
                    lngDouble = Double.parseDouble(lng);
                } catch (Exception e) {
                    e.printStackTrace();
                    latDouble = 0;
                    lngDouble = 0;
                }
                latLngList.add(new LatLng(latDouble, lngDouble));
            }
        }
        if (mArrivalLatLngList != null && mArrivalLatLngList.size() > 0) {
            for (com.yxhl.protobuf.Location location : mArrivalLatLngList) {
                String lat = location.getLat();
                String lng = location.getLng();
                double latDouble;
                double lngDouble;
                try {
                    latDouble = Double.parseDouble(lat);
                    lngDouble = Double.parseDouble(lng);
                } catch (Exception e) {
                    e.printStackTrace();
                    latDouble = 0;
                    lngDouble = 0;
                }
                latLngList.add(new LatLng(latDouble, lngDouble));
            }
        }
        mRootFrame.postDelayed(new Runnable() {
            @Override
            public void run() {
                animateMoveTo(latLngList, MOVE_PADDING);
            }
        }, SECOND_ANIMATE_MOVE_DELAY);
    }

    private void initArguments() {
        Bundle arguments = getArguments();
        if (arguments != null) {
            mOrderId = arguments.getString(ARGUMENT_KEY_EXPRESS_CAR_SCHEDULE_MAP, "");
        }
    }

    @OnClick(R.id.frame_express_car_service_location)
    public void onLocationIconClick(View view) {
        Location location = mMapView.getMap().getMyLocation();
        if (location != null) {
            animateMoveTo(new LatLng(location.getLatitude(), location.getLongitude()), MAP_ZOOM_LEVEL);
        }
    }

    @OnClick(R.id.iv_express_car_service_driver_info_phone)
    public void onDriverInfoPhoneIconClick(View view) {
        showPhonePopupWindow();
    }

    private void showPhonePopupWindow() {
        if (mPhonePopupWindow != null)
            mPhonePopupWindow.showAtBottomLocation(mRootFrame);
        else
            createPhonePopUpWindow(mDriverMobile);
    }

    /**
     * create phone popup window
     */
    private void createPhonePopUpWindow(String driverMobile) {
        onRxBusEvent();
        mPhonePopupWindow = new DriverPhonePopupWindow.Builder(mActivity)
                .setTitle(driverMobile)
                .setContent(getString(R.string.special_car_popup_dial_content))
                .setCancel(getString(R.string.special_car_dialog_cancel))
                .setEnsure(getString(R.string.special_car_popup_dial_confirm))
                .onPositive(new DriverPhonePopupWindow.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull DriverPhonePopupWindow popupWindow) {
                        if (PermissionHelper.checkPhonePermission(mActivity)) {
                            DeviceUtils.dialTelPhone(mActivity, mDriverMobile);
                        } else {
                            PermissionHelper.takeCallPhonePermission(mActivity, PermissionHelper.REQUEST_CODE_CALL_SPECIAL_CAR_DRIVER);
                        }
                    }
                })
                .onNegative(new DriverPhonePopupWindow.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull DriverPhonePopupWindow popupWindow) {
                        popupWindow.dismiss();
                    }
                }).build();
    }

    public void onRxBusEvent() {
        getSubscription().add(toSubscription(DialTelephoneEvent.class,
                new Action1<DialTelephoneEvent>() {
                    @Override
                    public void call(DialTelephoneEvent dialTelephoneEvent) {
                        if (dialTelephoneEvent.getFromDirection() == DialTelephoneEvent.FROM_SCHEDULE_DRIVER_MOBILE) {
                            if (!TextUtils.isEmpty(mDriverMobile)) {
                                DeviceUtils.dialTelPhone(mActivity, mDriverMobile);
                            }
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        onRxBusEvent();
                    }
                }
        ));
    }

    @Override
    public void renderDataOnSuccess(BizOrderResponse response) {
        OrderBizType orderBizType = response.getOrderBizType();
        switch (orderBizType) {
            case SPECIAL_BUS_WAY:
                mDepartLatLngList = response.getLnglatsList();
                mArrivalLatLngList = response.getElnglatsList();
                scheduleMapPresenter.refreshExpressCarMileageMarkersInMap(mMapView.getMap(),
                        mDepartLatLngList, mArrivalLatLngList);
                break;
            case SPECIAL_BUS_TIME:
                mDepartLatLngList = response.getLnglatsList();
                mArrivalLatLngList = response.getElnglatsList();
                scheduleMapPresenter.refreshExpressCarTimingMarkersInMap(mMapView.getMap(), mDepartLatLngList);
                break;
        }
    }

    @Override
    public void renderDataOnFailure(String resultMessage) {
        PromptUtils.showShort(getContext(), resultMessage);
    }

    @Override
    public void setupToolBarHeaderStatus(String title, String operation) {
        ((ExpressCarScheduleActivity) mActivity).setToolbar(title, operation);
    }

    @Override
    public void setupScheduleBarStatus(String message, boolean iconVisibility) {
        if (iconVisibility) {
            mScheduleIconIv.setVisibility(View.VISIBLE);
        } else {
            mScheduleIconIv.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(message)) {
            mScheduleTitleTv.setText(message);
        }
    }

    @Override
    public void setupDriverInfoStatus(String driverName, String driverCarInfo, int judgePoint, boolean isPhoneIconVisible, String mobile) {
        if (!TextUtils.isEmpty(driverName)) {
            mDriverInfoNameTv.setVisibility(View.VISIBLE);
            if (isPhoneIconVisible) {
                mDriverInfoPhoneIv.setVisibility(View.VISIBLE);
            } else {
                mDriverInfoPhoneIv.setVisibility(View.INVISIBLE);
            }

            mDriverInfoNameTv.setText(driverName);
            mCarInfoTv.setText(driverCarInfo);
            mOverallRatingTv.setText("综合评分：" + judgePoint);
        } else {
            mDriverInfoNameTv.setVisibility(View.INVISIBLE);
            mDriverInfoPhoneIv.setVisibility(View.INVISIBLE);
        }
        mDriverMobile = mobile;
    }

    @Override
    public void updateDataBetweenRideStatus(int fromRideStatus, int toRideStatus, String driverMobile) {
        if (fromRideStatus == SpecialCarRideStatus.DISPATCH
                && toRideStatus == SpecialCarRideStatus.UN_GET_IN) {
            setupScheduleBarStatus(getString(R.string.schedule_un_send_wait), false);
            createPhonePopUpWindow(driverMobile);
        } else if (fromRideStatus == SpecialCarRideStatus.UN_GET_IN
                && toRideStatus == SpecialCarRideStatus.DISPATCH) {
            setupScheduleBarStatus(getString(R.string.schedule_un_send_wait_again), true);
        }
    }

    @Override
    public void updateTimeAndDistanceValue(String runTime, String runDistance) {
        if (!TextUtils.isEmpty(runTime)) {
            mScheduleTimeTv.setText("时间 " + runTime + "");
        }
        if (!TextUtils.isEmpty(runDistance)) {
            mScheduleDistance.setText("里程 " + runDistance + "公里");
        }
    }

    @Override
    public void showArrivalDialog(final BizOrderResponse bizOrderResponse) {
        //弹出行程结束对话框  跳到 评论页面
        if (arrivalDialog == null) {
            arrivalDialog = new ZMDialog.Builder(mActivity)
                    .setMessage("本次行程已结束")
                    .setPositiveMessage(getString(R.string.confirm))
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
//                            AppraisalDriverInfo driverInfo = new AppraisalDriverInfo();
//                            ExpressCarScheduleActivity activity = (ExpressCarScheduleActivity) mActivity;
//                            driverInfo.setOrderId(DiskCacheUtils.getInstance(activity).getExpressCarOrderId())
//                                    .setDriverName(bizOrderResponse.getDriverName())
//                                    .setHistoryScore((int) bizOrderResponse.getDriverJudgePoint())
//                                    .setPlateNumber(bizOrderResponse.getVehicleNo());
//                            getAppComponent().navigator().navigateToAppraisal(activity, driverInfo);
                            mActivity.finish();
                        }
                    }).show();
            isPollingStop = scheduleMapPresenter.stopPolling(mActivity);
        }
    }

    @Override
    public void showPaymentDialog(final BizOrderResponse bizOrderResponse) {
        final BizOrder bizOrder = bizOrderResponse.getOrderFieldsesList().get(0);
        if (paymentDialog == null) {
            paymentDialog = new ZMDialog.Builder(mActivity)
                    .setTitle("行程结束")
                    .setMessage("您本次行程花费" + bizOrder.getTotalFee() + "元")
                    .setPositiveMessage("去支付")
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
                            CarPaymentInfo paymentInfo = new CarPaymentInfo();
                            OrderBizType bizType = bizOrderResponse.getOrderBizType();
                            CarPaymentEntrance mCarPaymentEntrance = getCarPaymentEntrance(bizType);
                            paymentInfo
                                    .setCarPaymentEntrance(mCarPaymentEntrance)
                                    .setOrderId(bizOrder.getOrderSerial())
                                    .setBizType(bizType.getNumber())
                                    .setTotalFee(String.valueOf(bizOrder.getTotalFee()))
                                    .setDriverName(bizOrder.getDriverName())
                                    .setPlateNumber(bizOrder.getVehicleNo())
                                    .setHistoryScore(Double.valueOf((TextUtils.isEmpty(bizOrder.getAvgDriverPoint())) ? "4" : bizOrder.getAvgDriverPoint()));
                            getAppComponent().navigator().navigateToSpecialCarPayment(mActivity, paymentInfo);
                            mActivity.finish();
                        }

                        @Override
                        public void onError(Throwable e) {
                            super.onError(e);
                        }
                    }).show();
            isPollingStop = scheduleMapPresenter.stopPolling(mActivity);
        }
    }

    @Nullable
    private CarPaymentEntrance getCarPaymentEntrance(OrderBizType bizType) {
        CarPaymentEntrance mCarPaymentEntrance = null;
        switch (bizType) {
            case SPECIAL_BUS_WAY:
                mCarPaymentEntrance = CarPaymentEntrance.CAR_PAYMENT_ENTRANCE_EXPRESS_CAR_WAY;
                break;
            case SPECIAL_BUS_TIME:
                mCarPaymentEntrance = CarPaymentEntrance.CAR_PAYMENT_ENTRANCE_EXPRESS_CAR_TIME;
                break;
        }
        return mCarPaymentEntrance;
    }

    @Override
    public void showTimeOutDialog() {
        if (timeOutDialog == null) {
            timeOutDialog = new ZMDialog.Builder(mActivity)
                    .setMessage(getString(R.string.special_car_dialog_time_out_message))
                    .setPositiveMessage(getString(R.string.special_car_dialog_confirm))
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
                            getActivity().finish();
                        }
                    })
                    .show();
            isPollingStop = scheduleMapPresenter.stopPolling(mActivity);
        }
    }

    @Override
    public void showDriverCloseDialog() {
        if (driverCloseDialog == null) {
            driverCloseDialog = new ZMDialog.Builder(mActivity)
                    .setMessage(getString(R.string.special_car_dialog_driver_close_order_message))
                    .setPositiveMessage(getString(R.string.special_car_dialog_confirm))
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
                            getActivity().finish();
                        }
                    })
                    .show();
            isPollingStop = scheduleMapPresenter.stopPolling(mActivity);
        }
    }


    @Override
    public void showInvalidDataDialog() {
        if (invalidDataDialog == null) {
            invalidDataDialog = new ZMDialog.Builder(mActivity)
                    .setMessage(getString(R.string.special_car_dialog_invalidate_order))
                    .setPositiveMessage(getString(R.string.special_car_dialog_confirm))
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
                            getActivity().finish();
                        }
                    })
                    .show();
            isPollingStop = scheduleMapPresenter.stopPolling(mActivity);
        }
    }

    @Override
    public void routeResultFailure() {

    }

     /*--------Animator--------*/

    @Override
    public void startEnterAnimatorForScheduleBar() {
        scheduleAnimatorHelper.startEnterAnimatorForScheduleBar(mScheduleIconIv, mScheduleBarRl);
    }

    @Override
    public void startExitAnimatorForScheduleBar() {
        scheduleAnimatorHelper.startExitAnimatorForScheduleBar(mScheduleBarRl);
    }

    @Override
    public void startEnterAnimatorForDriverInfoAndScheduleBar(boolean runNextAnimator) {
        scheduleAnimatorHelper.startEnterAnimatorForDriverInfo(mDriverInfoRl, mHeaderContainerRl, runNextAnimator);
    }

    @Override
    public void startExitAnimatorForDriverInfo() {
        scheduleAnimatorHelper.startExitAnimatorForDriverInfo(mDriverInfoRl, mHeaderContainerRl);
    }

    @Override
    public void startTimeDistanceInfoBarAnimator(boolean needUpTranslation) {
        scheduleAnimatorHelper.startTimeDistanceInfoBarAnimator(mScheduleTimeDistanceBar, needUpTranslation);
    }

}
